#include "brightness_custom.h"
#include "flash_act.h"
#include "systime.h"
#include "indicator.h"
#include "relay_ctrl.h"
#include "adc_driver.h"
#include "key.h"

#define DEF_PROCESS_TIME_S 5 // 单位：s  设置环境光亮度整个过程的时间
#define DEF_SAMPLE_TIME_MS 50

typedef enum
{
    BRIGHTNESS_CUSTOM_INIT,      // 初始化状态
    BRIGHTNESS_CUSTOM_ENTER,     // 进入自定义模式
    BRIGHTNESS_CUSTOM_LIGHT_OFF, // 小灯熄灭状态
    BRIGHTNESS_CUSTOM_SAMPLING,  // 采样状态
    BRIGHTNESS_CUSTOM_FINISHED,  // 完成状态

} brightness_custom_state_e;

static struct
{
    timestamp_t blink_timeout;       // 小灯闪烁的超时时间
    timestamp_t sample_timeout;      // 采样的超时时间
    brightness_custom_state_e state; // 当前状态
    uint8_t is_finished;             // 是否完成标志
} brightness_custom_process_t;

static struct
{
    relay_state_e relay_state;
    IND_SW ind_sw;
    uint16_t min_brightness_value; // 环境光亮度的最小值
    uint16_t sample_value;         // 当前采样值
    uint8_t sample_cnt;            // 采样计数
} brightness_custom_ctx;

void brightness_custom_init(void)
{
    brightness_custom_process_t.state = BRIGHTNESS_CUSTOM_INIT;
    brightness_custom_process_t.is_finished = FALSE;

    brightness_custom_ctx.relay_state = RELAY_OFF;
    brightness_custom_ctx.ind_sw = IND_OFF;
    brightness_custom_ctx.min_brightness_value = 0;
    brightness_custom_ctx.sample_value = 0;
    brightness_custom_ctx.sample_cnt = 0;
}

void brightness_custom_process_task(void)
{
    switch (brightness_custom_process_t.state)
    {
    case BRIGHTNESS_CUSTOM_INIT:
        if (!brightness_custom_process_t.is_finished)
        {
            brightness_custom_process_t.state = BRIGHTNESS_CUSTOM_ENTER;
        }
        break;
    case BRIGHTNESS_CUSTOM_ENTER:
        set_key_switch(KEY_DISABLE); // 按键失能
        brightness_custom_ctx.ind_sw = get_indicator_sw();
        brightness_custom_ctx.relay_state = get_relay_sw();
        set_indicator_sw(IND_CUSTOM); // 小灯闪烁指示
        set_relay_sw(RELAY_OFF);
        relative_time_add_sec(&brightness_custom_process_t.blink_timeout, DEF_PROCESS_TIME_S);
        brightness_custom_ctx.sample_cnt = 0;
        brightness_custom_ctx.sample_value = 0;
        brightness_custom_ctx.min_brightness_value = 0;
        brightness_custom_process_t.state = BRIGHTNESS_CUSTOM_LIGHT_OFF;
        break;
    case BRIGHTNESS_CUSTOM_LIGHT_OFF:
        if (!is_indicator_bright())
        { // 等待小灯处于熄灭状态
            relative_time_add_ms(&brightness_custom_process_t.sample_timeout, DEF_SAMPLE_TIME_MS);
            brightness_custom_process_t.state = BRIGHTNESS_CUSTOM_SAMPLING;
        }
        break;
    case BRIGHTNESS_CUSTOM_SAMPLING:
        if (is_indicator_bright())
        {
            brightness_custom_process_t.state = BRIGHTNESS_CUSTOM_LIGHT_OFF;
        }
        else if (is_relative_time_timeout(&brightness_custom_process_t.sample_timeout))
        {
            relative_time_add_ms(&brightness_custom_process_t.sample_timeout, DEF_SAMPLE_TIME_MS);
            brightness_custom_ctx.sample_value = get_photoD_val();
            if (brightness_custom_ctx.sample_cnt == 0)
            {
                brightness_custom_ctx.min_brightness_value = brightness_custom_ctx.sample_value;
            }
            if (brightness_custom_ctx.min_brightness_value > brightness_custom_ctx.sample_value)
            {
                brightness_custom_ctx.min_brightness_value = brightness_custom_ctx.sample_value; // 采集取最小值
            }
            brightness_custom_ctx.sample_cnt++;
            if (brightness_custom_ctx.sample_cnt >= 50)
            {
                write_brightness_custom_value(brightness_custom_ctx.min_brightness_value);
                brightness_custom_process_t.state = BRIGHTNESS_CUSTOM_FINISHED;
            }
        }
        break;
    case BRIGHTNESS_CUSTOM_FINISHED:
        if (is_relative_time_timeout(&brightness_custom_process_t.blink_timeout))
        {
            set_relay_sw(brightness_custom_ctx.relay_state);
            set_indicator_sw(brightness_custom_ctx.ind_sw);
            set_key_switch(KEY_ENABLE); // 按键使能
            brightness_custom_process_t.is_finished = TRUE;
            brightness_custom_process_t.state = BRIGHTNESS_CUSTOM_INIT;
        }
        break;

    default:
        break;
    }
}

uint8_t is_brightness_custom_finish(void)
{
    return brightness_custom_process_t.is_finished;
}

uint8_t read_brightness_custom_value(uint16_t *val)
{
    if (Ok == read_user_halfword(val))
    {
        return TRUE;
    }

    return FALSE;
}

void write_brightness_custom_value(uint16_t val)
{
    write_user_halfword(val);
}
